set auto_path [concat [pwd]/../../pkg/tkMD $auto_path ]
#start script
if {[lsearch $argv --DEBUG] >= 0 } {
set DEBUG true
} else {
set DEBUG false
}

#main
proc main {argc argv} {
global argv0 tcl_version

if [ catch {package require tkMD 1.1}] { puts "$argv0 needs tkMD 1.1, please install it first!";exit}
namespace import SimTask::*
namespace import Path::*

if { $tcl_version < 8.5 } {
    puts "Cannot run, tkMD requires Tcl version higher than 8.5."
    exit
}

#args help 
proc print_help {} {
    global argv0
 puts "Usage:\n $argv0 paramterfile \[--peptide peptide1 peptide2\] \[ --petidelist peptidefile1 peptidefile2 ...\] \[--set varname value1 \[value2\]...\] " 
 puts "Input:\n"
 puts "    paramterfile : a file to setup all the parameters needed for simulation (find example files in the current folder)."
 puts "    \[--peptide peptide1 peptide2 ...\] : list the peptides going to be simulated. "
 puts "    \[--peptidelist peptidefile1 peptidefile2 ...\] : files that list the peptides going to be simulated."
 puts "    \[--runpath \] : directory to save simulation files. Default is a subfolder of the current directory named by the parameterfile. If there already are simulation files in the directory, only unfinished simulations(without eql_min.crd) will be redo."
 puts "    \[--pdbpath \] : place to look for pdb files." 
 puts "    \[--templatepath \] : place to look for template files."
 puts "    \[--use-charmm \] : which charmm binary file is going to be used."
 puts "    \[--ntimes \] : run each simulation n times."
 puts "    \[--clean \] : remove all the charmm output files after the simulation to save disk space. Otherwise those files will be compressed into tar files."

}

proc parse_cmd {} {
    global argc argv 
    if {$argc < 1} {
        puts "Paramter File is required!"
        print_help
        exit
    }
    #get options 
    set options [lsearch -all -glob $argv "--*" ]
    set i 0
    foreach idx  $options {
    set end [expr [lindex $options [expr $i+1]]-1]
    if {$end <0} {set end end}
    set name [lindex $argv $idx]
    set value [lrange $argv [expr $idx +1] $end]
    set Option($name) $value
    incr i
    }
        # do the parsing for required arguments
    global parameterfile basepath SimTask::RunPath SimTask::Pdbpath
    set parameterfile [lindex $argv 0]
    if ![file exists $parameterfile] {puts "Parameter File $parameterfile Do not exists!";print_help;exit}
    set basename [lindex [split [file rootname $parameterfile] /] end]
    set SimTask::RunPath [pwd]/$basename 
    uplevel 1 "source $parameterfile"
    if [catch {set basepath [lindex $argv 1]}] {set basepath [pwd]}
    if [string match $basepath --*] {set basepath [pwd]} 
    # do the parsing for options 
    global peptides
    foreach name [lsort [array names Option]] {
        switch -nocase $name {
        --peptide { 
                Data::ladd peptides $Option(--peptide) 
            }
        --peptidelist {
                foreach pdblistfile $Option(--peptidelist) {
                 Data::ladd peptides [regexp -all -inline -- {\S+} [read [open $pdblistfile r] ]]
                }
            }
        --output-pattern {
            global outputpattern
            set outputpattern [lindex $Option(--output-pattern) 0]
        }
        --pdbpath {
                set SimTask::Pdbpath [lindex $Option(--pdbpath) 0]
                if ![file isdirectory ${SimTask::Pdbpath}] { 
                    puts "PDB path ${SimTask::Pdbpath} is not correct!"
                    print_help
                    exit
                }
                if ![file exists ${SimTask::Pdbpath}] {
                    puts "PDB path ${SimTask::Pdbpath} do not exist!"
                    print_help
                    exit
                }
            }
         --runpath {
                set SimTask::RunPath [lindex $Option(--runpath) 0]
                if {[string match [file pathtype $SimTask::RunPath] 'relative'] == 0 } { set SimTask::RunPath [pwd]/$SimTask::RunPath }
                if ![file isdirectory ${SimTask::RunPath}] { 
                    puts "Output path ${SimTask::RunPath} is not correct!"
                    print_help
                    exit
                }
                if ![file exists ${SimTask::RunPath}] {
                    puts "Output path ${SimTask::RunPath} do not exist!"
                    print_help
                    exit
                }
         }
         --templatepath {
                set SimTask::TemplatePath [lindex $Option(--templatepath) 0]
                if ![file isdirectory ${SimTask::TemplatePath}] { 
                    puts "Template path ${SimTask::TemplatePath} is not correct!"
                    print_help
                    exit
                }
                if ![file exists ${SimTask::TemplatePath}] {
                    puts "Template path ${SimTask::TemplatePath} do not exist!"
                    print_help
                    exit
                }
         }
         --jobpath {
                set SimTask::JobPath [lindex $Option(--jobpath) 0]
                if ![file isdirectory ${SimTask::JobPath}] { 
                    puts "Job path ${SimTask::JobPath} is not correct!"
                    print_help
                    exit
                }
                if ![file exists ${SimTask::JobPath}] {
                    puts "Job path ${SimTask::JobPath} do not exist!"
                    print_help
                    exit
                }
         }
         --use-charmm {
               set SimTask::Charmmbin [lindex $Option(--use-charmm) 0]
         }
         --ntimes {
               global nreplica
               set nreplica [lindex $Option(--ntimes) 0]
         }
         --clean {
               global docleanning
                set docleanning true
         }
         --set {
               foreach {key value} $Option(--set) {
                upvar 1 $key Key
                set Key $value
               }
         }
        }
    }
}


##Default simulation environment
global SimTask::PdbPath SimTask::TemplatePath SimTask::JobPath SimTask::RunPath SimTask::Njobs nreplica docleanning
set SimTask::PdbPath [pwd]/../pdb 
set SimTask::TemplatePath [pwd]/template
set SimTask::JobPath [pwd]/job
set SimTask::RunPath [pwd]/run

set outputpattern array(key)_value/
##Default simulation parameters
global type temp thick ionc anfr preptime eqltime peptides orientation
set type { water neutral anionic}
set temp 298
set thick 26
set ionc 0.1
set anfr 0.3
set preptime 0.001
set eqltime 0.001
set orientation { o0 }
set peptides {}
set nreplica 4
set docleanning false
parse_cmd
VarSpace options { type temp thick ionc anfr orientation preptime eqltime }
## Validate parameters
if {[llength $peptides] <= 0} {
    puts "Please indicate which peptides to be simulated by set peptides in your parameter file or by supply --peptide/--petidelist option to command line."
    print_help
    exit
}
if [catch {set binpath [exec which $SimTask::Charmmbin]} ] {
    puts "Charmm Binary file does not exist or is not set up correctly!"
    print_help
    exit
}

## Start of the calculation
set timestamp [clock format [clock seconds] -format "%b %d %y - %T"]
puts "Start Simulation with { $argv0 $argv } @ $timestamp "
puts "==============================================================="
printEnv
puts "==============================================================="
puts "Peptides to be simulated:"
puts "==============================================================="
puts "$peptides"
puts "==============================================================="
puts "Parameters will be using for simulations: "
puts "==============================================================="
foreach var $options(*vars) {
   puts "$var = $options(def,$var)"
}
puts "==============================================================="

foreach peptide $peptides {
set timestamp [clock format [clock seconds] -format "%b %d %y - %T"]
puts "Prepare: $peptide , Current time: $timestamp "
puts "==============================================================="

if [catch {
	prepfiles $peptide {o0.crd o1.crd o2.crd o3.crd o4.crd pept.psf}
	run $nreplica $peptide run.inp options --combinejob run orientation --skip { file exists eql_min.crd } --post { tar -czf run.out.tar.gz run.out; rm run.out}
	} error] {	puts "ERROR: $error" }
}
waitfor run 
if $docleanning { rmfiles $SimTask::RunPath  *.out }
puts "Simulations are all finished. But check the error log(under the job path) to see if all simulations are carried out correctly. Errors are suppressed during the simulation to prevent the program exits accidentally."
} ;#end of main

## Execuate 
if [catch {main $argc $argv } error ] {
    if $DEBUG { puts $errorInfo } else { puts $error} 
}


exit


